//
//  stats_client_processor.cpp
// ~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2013-2014 Razvan Coca (razvan dot coca at  gmail dot com)
// 


#include <boost/logic/tribool.hpp>
#include "stats_client_processor.hpp"

namespace components
{
namespace protocol
{

stats_client_processor::stats_client_processor(std::string const & cluster, std::string const & node):
    cluster_(cluster),node_(node),current_state(start),trans_id_(0),seq_no_(0)
{
    DLOG(INFO)<<__FUNCTION__;
    current_state=start;
}
void stats_client_processor::init_trans(stats_message_t& msg)
{
    trans_id_=std::rand();
    seq_no_=0;
    trans_label t;
    t.set_trans_id(trans_id_);
    t.set_seq_no(++seq_no_);
    msg.mutable_trans()->CopyFrom(t);
}
void stats_client_processor::update_trans(stats_message_t& msg)
{
    seq_no_=msg.trans().seq_no();
    trans_label t;
    t.set_trans_id(trans_id_);
    t.set_seq_no(++seq_no_);
    msg.mutable_trans()->CopyFrom(t);
}

void stats_client_processor::update_source(stats_message_t& msg)
{
    node_id n;
    n.set_cluster(cluster_);
    n.set_node(node_);
    msg.mutable_source()->CopyFrom(n);
}
boost::logic::tribool stats_client_processor::process_request_set(stats_message_t& msg,udp_endpoint_t& peer,boost::system::error_code const &ec)
{

    auto event=msg.type();
    if(current_state!=start)
    {
        DLOG(INFO)<<__FUNCTION__<<" indeterminate";
        return boost::indeterminate;
    }
    if(event!=stats_message_t::request_set)
    {
        DLOG(INFO)<<__FUNCTION__<<" indeterminate";
        return boost::indeterminate;
    }
    current_state=replies;

    init_trans(msg);
    update_source(msg);
    DLOG(INFO)<<__FUNCTION__<<" true";
    return true;
}
boost::logic::tribool stats_client_processor::process_request_get(stats_message_t& msg,udp_endpoint_t& peer,boost::system::error_code const &ec)
{

    auto event=msg.type();
    if(current_state!=start)
    {
        DLOG(INFO)<<__FUNCTION__<<" indeterminate";
        return boost::indeterminate;
    }
    if(event!=stats_message_t::request_get)
    {
        DLOG(INFO)<<__FUNCTION__<<" indeterminate";
        return boost::indeterminate;
    }
    current_state=replies;

    init_trans(msg);
    update_source(msg);
    data_.clear();
    DLOG(INFO)<<__FUNCTION__<<" true";
    return true;
}
boost::logic::tribool stats_client_processor::process_reply(stats_message_t& msg,udp_endpoint_t& peer,boost::system::error_code const &ec)
{

    auto event=msg.type();
    if(current_state!=replies)
    {
        DLOG(INFO)<<__FUNCTION__<<" indeterminate";
        return boost::indeterminate;
    }
    if(event!=stats_message_t::reply)
    {
        DLOG(INFO)<<__FUNCTION__<<" indeterminate";
        return boost::indeterminate;
    }
    current_state=replies;
    data_.push_back(msg);
    update_trans(msg);
    DLOG(INFO)<<__FUNCTION__<<" true";
    return true;
}
boost::logic::tribool stats_client_processor::process_end(stats_message_t& msg,udp_endpoint_t& peer,boost::system::error_code const &ec)
{

    auto event=msg.type();
    if(current_state!=replies)
    {
        DLOG(INFO)<<__FUNCTION__<<" indeterminate";
        return boost::indeterminate;
    }
    if(event!=stats_message_t::end)
    {
        DLOG(INFO)<<__FUNCTION__<<" indeterminate";
        return boost::indeterminate;
    }
    current_state=start;
    data_.push_back(msg);

    update_trans(msg);
    DLOG(INFO)<<__FUNCTION__<<" true";
    return true;
}
boost::logic::tribool stats_client_processor::process_timeout(stats_message_t& msg,udp_endpoint_t& peer,boost::system::error_code const &ec)
{

    auto event=msg.type();
    if(current_state!=replies)
    {
        DLOG(INFO)<<__FUNCTION__<<" indeterminate";
        return boost::indeterminate;
    }
    if(event!=stats_message_t::timeout)
    {
        DLOG(INFO)<<__FUNCTION__<<" indeterminate";
        return boost::indeterminate;
    }
    current_state=start;
    DLOG(INFO)<<__FUNCTION__<<" true";
    return true;
}


}//namespace protocol
}//namespace components
